Wstęp, cele

W tej pracy domowej dla 3-wymiarowego zbioru danych przetestuję 2 metody klasteryzacji:

oraz w celu wyznaczenia optymalnej liczby klastrów skorzystam z 3 metryk:

Ponadto, użyję metody wizualnej oraz wykorzystam pakiet NbClust.

Ładowanie danych oraz standaryzacja

data <- read.csv("../../clustering_R3.csv")

dataS <- as.data.frame(scale(data, scale = TRUE, center = TRUE))

Wizualizacja zbioru danych

plot_ly(x = dataS$X1, y = dataS$X2, z = dataS$X3, type = "scatter3d", mode = "markers")

kmean & hclust

km <- list(numeric(0)) # initializing variable containing results
hc <- list(numeric(0)) # initializing variable containing results

for (i in 1:10){
  km[[i]] <- kmeans(dataS, centers = i)$cluster
}

d <- dist(dataS)
for (i in 1:10){
  hc[[i]] <- cutree(hclust(d, method = "average"), i)
}

Opis stosowanych metryk

Silhouette

Współczynnik Solhouette jest miarą tego jak podobna jest dana obserwacja do swojego własnego klastra (cohesion) w porównaniu do innych występujących klastrów (separation). Silhouette przyjmuje wartości od -1 do +1, gdzie im wyższa wartość tym lepiej dana obserwacja jest przypisana do swojego klastra i tym mniejsza jest jej relacja z innymi klastrami.

Im większy (bliższy 1) tym lepszy.

Calinski Harabasz index

Ten indeks jest określony jako stosunek między miarą rozproszenia wewnątrz klastra do miary rozproszenia międzyklastrowego.

Im większy tym lepszy.

Dunn’s index

Jest to stosunek minimalnej odległości między 2 obserwacjami w różnych klastrach do maksymalnej odległości między 2 różnymi obserwacjami należącymi do danego klastra.

Dunn’s index = minimum intercluster distance / maximum cluster diameter

Im większy tym lepszy.

Wspolczynniki Silhouette & Calinski-Harabasz index & Dunn’s index

silhouette.km <- list(numeric(0))
silhouette.hc <- list(numeric(0))
ch.km <- list(numeric(0))
ch.hc <- list(numeric(0))
dunn.km <- list(numeric(0))
dunn.hc <- list(numeric(0))

for (i in 2:10){
  staty.km <- cluster.stats(d, km[[i]]) # fpc library
  staty.hc <- cluster.stats(d, hc[[i]]) # fpc library
  
  silhouette.km[[i]] <- staty.km$avg.silwidth 
  silhouette.hc[[i]] <- staty.hc$avg.silwidth
  ch.km[[i]] <- staty.km$ch
  ch.hc[[i]] <- staty.hc$ch
  dunn.km[[i]] <- staty.km$dunn
  dunn.hc[[i]] <- staty.hc$dunn
}

Wykresy

plot(x = 1:10, y = silhouette.km, main = "SILHOUETTE - kmeans", 
     ylab = "Silhouette index", xlab = "Number of clusters") # 2

2 - najlepsza liczba klastrów wg powyższej metryki

plot(x = 1:10, y = silhouette.hc, main = "SILHOUETTE - hclust", 
     ylab = "Silhouette index", xlab = "Number of clusters") # 2

2 - najlepsza liczba klastrów wg powyższej metryki

plot(x = 1:10, y = ch.km, main = "CALINSKI HARABASZ - kmeans", 
     ylab = "Calinski Harabasz index", xlab = "Number of clusters") # 7

7 - najlepsza liczba klastrów wg powyższej metryki

plot(x = 1:10, y = ch.hc, main = "CALINSKI HARABASZ - hclust", 
     ylab = "Calinski Harabasz index", xlab = "Number of clusters") # 7

7 - najlepsza liczba klastrów wg powyższej metryki

plot(x = 1:10, y = silhouette.km, main = "DUNN - kmeans", 
     ylab = "Dunn's index", xlab = "Number of clusters") # 2

2 - najlepsza liczba klastrów wg powyższej metryki

plot(x = 1:10, y = silhouette.hc, main = "DUNN - hclust", 
     ylab = "Dunn's index", xlab = "Number of clusters") # 2

2 - najlepsza liczba klastrów wg powyższej metryki

Wnioski z wykresów

Najczęściej najlepsza występująca liczba klastrów to 2. Dodam również wizualizację dla 7 klastrów w celu porównania.

Wizualizacja najlepszych klasteryzacji

kmeans - wyniki 3D

# kmeans - 2 centers
plot_ly(x = dataS$X1, y = dataS$X2, z = dataS$X3, type = "scatter3d", mode = "markers", color = km[[2]])
# kmeans - 7 centers
plot_ly(x = dataS$X1, y = dataS$X2, z = dataS$X3, type = "scatter3d", mode = "markers", color = km[[7]])

hclust - wyniki 3D

# clust 2
plot_ly(x = dataS$X1, y = dataS$X2, z = dataS$X3, type = "scatter3d", mode = "markers", color = hc[[2]])
# clust 7
plot_ly(x = dataS$X1, y = dataS$X2, z = dataS$X3, type = "scatter3d", mode = "markers", color = hc[[7]])

Zastosowanie NbClust

nc <- NbClust(data = dataS, method = "complete")

## *** : The Hubert index is a graphical method of determining the number of clusters.
##                 In the plot of Hubert index, we seek a significant knee that corresponds to a 
##                 significant increase of the value of the measure i.e the significant peak in Hubert
##                 index second differences plot. 
## 

## *** : The D index is a graphical method of determining the number of clusters. 
##                 In the plot of D index, we seek a significant knee (the significant peak in Dindex
##                 second differences plot) that corresponds to a significant increase of the value of
##                 the measure. 
##  
## ******************************************************************* 
## * Among all indices:                                                
## * 6 proposed 2 as the best number of clusters 
## * 1 proposed 3 as the best number of clusters 
## * 7 proposed 4 as the best number of clusters 
## * 1 proposed 8 as the best number of clusters 
## * 5 proposed 9 as the best number of clusters 
## * 2 proposed 10 as the best number of clusters 
## * 2 proposed 15 as the best number of clusters 
## 
##                    ***** Conclusion *****                            
##  
## * According to the majority rule, the best number of clusters is  4 
##  
##  
## *******************************************************************
nc$Best.nc # 4
##                      KL      CH Hartigan     CCC    Scott   Marriot
## Number_clusters  4.0000    9.00    3.000  9.0000    4.000         4
## Value_Index     45.0489 2745.67 1736.772 55.6771 2623.278 295636937
##                   TrCovW   TraceW Friedman   Rubin Cindex      DB
## Number_clusters      4.0   4.0000   9.0000  9.0000 9.0000 10.0000
## Value_Index     527340.5 877.7151  45.9451 -6.7888 0.2014  0.6732
##                 Silhouette   Duda PseudoT2  Beale Ratkowsky     Ball
## Number_clusters     10.000 2.0000   2.0000 2.0000    2.0000   4.0000
## Value_Index          0.601 0.6913 134.3895 0.7576    0.4835 355.3094
##                 PtBiserial   Frey McClain   Dunn Hubert SDindex Dindex
## Number_clusters     4.0000 2.0000  2.0000 15.000      0  8.0000      0
## Value_Index         0.7869 2.5957  0.3707  0.057      0  2.6923      0
##                    SDbw
## Number_clusters 15.0000
## Value_Index      0.0909

Według NbClust oraz posługując się metodą wizualną można dojść do wniosku, że 4 najlepszą liczbą klastrów dla tego zbioru danych.

Niestety wybrane metody klasteryzacji źle klasteryzują dla tej liczby klastrów:

# kmeans - 4 centers
plot_ly(x = dataS$X1, y = dataS$X2, z = dataS$X3, type = "scatter3d", mode = "markers", color = km[[4]])
# clust 4 clusters
plot_ly(x = dataS$X1, y = dataS$X2, z = dataS$X3, type = "scatter3d", mode = "markers", color = hc[[4]])

Porzebna nam jest inna metoda, pomysłem był hclust z metodą ‘single’:

# THE BEST: hclust (single) with 4 clusters
plot_ly(x = dataS$X1, y = dataS$X2, z = dataS$X3, type = "scatter3d", mode = "markers", color = cutree(hclust(d, method = 'single'),4))

Metoda klasteryzacji hclust ‘single’ oraz liczba klastrów 4 wydają się być idealne.

Wnioski

Porównując metody klasteryzajci kmeans oraz hclust z metodą ‘average’ doszedłem do wniosku, że najlepsza dla nich liczba klastrów to 2 albo 7. Jednakże, lepsza od nich jest metoda klasteryzacji hierarchicznej hclust z wykorzystaniem metody ‘single’ dla 4 klastrów - taki wniosek wysnułem po zastosowaniu NbClust oraz obejrzeniu wizualnym zbioru danych w 3D.

Oświadczenie

Oświadczam, że niniejsza praca stanowiąca podstawę do uznania osiągnięcia efektów uczenia się z przedmiotu Wstęp do uczenia maszynowego została wykonana przeze mnie samodzielnie.